import { useState, useEffect } from 'react';
import styled from 'styled-components';
import * as Cesium from 'cesium';

// 样式化组件
const GridInfoPanel = styled.div`
  position: absolute;
  top: 20px;
  right: 20px;
  background-color: rgba(0, 21, 41, 0.75);
  border: 1px solid rgba(24, 144, 255, 0.5);
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
  color: white;
  padding: 15px;
  border-radius: 4px;
  z-index: 1000;
  width: 300px;
  max-width: 90%;
`;

const Title = styled.div`
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 10px;
  color: #1890ff;
  border-bottom: 1px solid rgba(24, 144, 255, 0.3);
  padding-bottom: 5px;
`;

const InfoGroup = styled.div`
  margin-bottom: 10px;
`;

const InfoLabel = styled.div`
  font-size: 12px;
  color: #a0cfff;
  margin-bottom: 2px;
`;

const InfoValue = styled.div`
  font-size: 14px;
  font-family: 'Courier New', monospace;
  background-color: rgba(0, 0, 0, 0.2);
  padding: 4px 6px;
  border-radius: 2px;
  word-break: break-all;
`;

const CoordinateRow = styled.div`
  display: flex;
  justify-content: space-between;
  margin-bottom: 5px;
`;

const CoordinateLabel = styled.div`
  color: #a0cfff;
  font-size: 12px;
  width: 40px;
`;

const CoordinateValue = styled.div`
  flex: 1;
  font-size: 12px;
`;

// 北斗网格字符映射常量
const GRID_CHAR_MAPPING = {
  // 第一级网格纬度编码（A-V对应0°-4°, 4°-8°, ..., 84°-88°）
  LAT_LEVEL_1: 'ABCDEFGHIJKLMNOPQRSTUV',
  // 第二级网格经度编码（0-B对应12进制）
  LON_LEVEL_2: '0123456789AB',
  // 第二级网格纬度编码（0-7对应8进制）
  LAT_LEVEL_2: '01234567',
  // 第三级网格Z序编码（0-5对应6个区域）
  LEVEL_3_Z_ORDER: '012345',
  // 第四级网格经度编码（0-E对应15进制）
  LON_LEVEL_4: '0123456789ABCDE',
  // 第四级网格纬度编码（0-9对应10进制）
  LAT_LEVEL_4: '0123456789',
  // 第五级网格经纬度编码（0-E对应15进制）
  LEVEL_5: '0123456789ABCDE',
  // 第七到十级网格经纬度编码（0-7对应8进制）
  LEVEL_7_10: '01234567'
};

interface BeidouGridToolProps {
  viewer: Cesium.Viewer | null;
  isVisible?: boolean;
}

// 北斗网格码工具组件
const BeidouGridTool: React.FC<BeidouGridToolProps> = ({ 
  viewer, 
  isVisible = true 
}) => {
  const [selectedPosition, setSelectedPosition] = useState<{
    longitude: number;
    latitude: number;
    height: number;
  } | null>(null);
  
  const [gridCodes, setGridCodes] = useState<{
    level1: string;
    level2: string;
    level3: string;
    level4: string;
    level5: string;
  }>({
    level1: '',
    level2: '',
    level3: '',
    level4: '',
    level5: ''
  });
  
  // 计算北斗网格二维编码（按GB/T 39409-2020标准）
  const calculateBeidouGridCode = (longitude: number, latitude: number, level: number): string => {
    // 检查是否是南北极区域 (±88°~90°)
    if (Math.abs(latitude) >= 88 && Math.abs(latitude) <= 90) {
      return calculatePolarGridCode(longitude, latitude, level);
    }
    
    // 非极地区域标准编码
    const isNorth = latitude >= 0;
    const latPrefix = isNorth ? 'N' : 'S';
    
    // 处理负经度（西经）
    let absLon = longitude;
    while (absLon < 0) {
      absLon += 360; // 将西经转换为0-360范围
    }
    absLon = absLon % 360; // 标准化到0-360范围
    
    const absLat = Math.abs(latitude);
    
    // 第1级网格：半球标识 + 经度 + 纬度
    // 经度：01-60（每6°一个单位）
    const lonLevel1 = Math.floor(absLon / 6) + 1; // 1-60范围
    const lonLevel1Str = lonLevel1.toString().padStart(2, '0');
    
    // 纬度：A-V（每4°一个单位，从赤道开始）
    const latLevel1Index = Math.min(Math.floor(absLat / 4), 21); // 0-21范围（A-V）
    const latLevel1Char = GRID_CHAR_MAPPING.LAT_LEVEL_1[latLevel1Index];
    
    // 构建一级网格码
    let gridCode = `${latPrefix}${lonLevel1Str}${latLevel1Char}`;
    
    // 如果只需要一级网格码，则返回
    if (level === 1) return gridCode;
    
    // 计算经纬度在该一级网格内的余数
    const lonRemainder = absLon % 6;
    const latRemainder = absLat % 4;
    
    // 第2级网格：12进制经度 + 8进制纬度
    // 经度：0-B（每30′一个单位）
    const lonLevel2 = Math.floor(lonRemainder / 0.5); // 0-11范围
    const lonLevel2Char = GRID_CHAR_MAPPING.LON_LEVEL_2[lonLevel2];
    
    // 纬度：0-7（每30′一个单位）
    const latLevel2 = Math.floor(latRemainder / 0.5); // 0-7范围
    const latLevel2Char = GRID_CHAR_MAPPING.LAT_LEVEL_2[latLevel2];
    
    // 添加二级网格码
    gridCode += `${lonLevel2Char}${latLevel2Char}`;
    
    // 如果只需要二级网格码，则返回
    if (level === 2) return gridCode;
    
    // 计算经纬度在该二级网格内的余数
    const lonRemainder2 = lonRemainder % 0.5;
    const latRemainder2 = latRemainder % 0.5;
    
    // 第3级网格：Z序曲线编码（0-5）
    // 将30′×30′网格划分为2×3份（经度15′、纬度10′）
    const lonLevel3 = Math.floor(lonRemainder2 / 0.25); // 0-1范围
    const latLevel3 = Math.floor(latRemainder2 / (1/6)); // 0-2范围
    
    // 计算Z序曲线索引
    const zOrderIndex = latLevel3 * 2 + lonLevel3; // 0-5范围
    const level3Char = GRID_CHAR_MAPPING.LEVEL_3_Z_ORDER[zOrderIndex];
    
    // 添加三级网格码
    gridCode += level3Char;
    
    // 如果只需要三级网格码，则返回
    if (level === 3) return gridCode;
    
    // 计算经纬度在该三级网格内的余数
    // 确定三级网格的经纬度范围
    const lonLevel3Base = Math.floor(absLon / 6) * 6 + Math.floor(lonRemainder / 0.5) * 0.5 + Math.floor(lonRemainder2 / 0.25) * 0.25;
    const latLevel3Base = Math.floor(absLat / 4) * 4 + Math.floor(latRemainder / 0.5) * 0.5 + Math.floor(latRemainder2 / (1/6)) * (1/6);
    
    // 计算经纬度在该三级网格内的位置
    const lonWithinLevel3 = absLon - lonLevel3Base;
    const latWithinLevel3 = absLat - latLevel3Base;
    
    // 第4级网格：15进制经度 + 10进制纬度（1′×1′）
    // 经度：0-E（每1′一个单位）
    const lonLevel4 = Math.floor(lonWithinLevel3 / (1/60)); // 0-14范围
    const lonLevel4Char = GRID_CHAR_MAPPING.LON_LEVEL_4[lonLevel4];
    
    // 纬度：0-9（每1′一个单位）
    const latLevel4 = Math.floor(latWithinLevel3 / (1/60)); // 0-9范围
    const latLevel4Char = GRID_CHAR_MAPPING.LAT_LEVEL_4[latLevel4];
    
    // 添加四级网格码
    gridCode += `${lonLevel4Char}${latLevel4Char}`;
    
    // 如果只需要四级网格码，则返回
    if (level === 4) return gridCode;
    
    // 计算经纬度在该四级网格内的余数
    const lonLevel4Base = lonLevel3Base + lonLevel4 * (1/60);
    const latLevel4Base = latLevel3Base + latLevel4 * (1/60);
    
    const lonWithinLevel4 = absLon - lonLevel4Base;
    const latWithinLevel4 = absLat - latLevel4Base;
    
    // 第5级网格：15进制经度 + 15进制纬度（4″×4″）
    // 经度：0-E（每4″一个单位）
    const lonLevel5 = Math.floor(lonWithinLevel4 / (4/3600)); // 0-14范围
    const lonLevel5Char = GRID_CHAR_MAPPING.LEVEL_5[lonLevel5];
    
    // 纬度：0-E（每4″一个单位）
    const latLevel5 = Math.floor(latWithinLevel4 / (4/3600)); // 0-14范围
    const latLevel5Char = GRID_CHAR_MAPPING.LEVEL_5[latLevel5];
    
    // 添加五级网格码
    gridCode += `${lonLevel5Char}${latLevel5Char}`;
    
    return gridCode;
  };
  
  // 计算南北极区域的网格编码
  const calculatePolarGridCode = (longitude: number, latitude: number, level: number): string => {
    const isPolarNorth = latitude >= 88;
    const prefix = isPolarNorth ? 'N' : 'S';
    
    // 第一级极地网格编码固定为"N000"或"S000"
    let gridCode = `${prefix}000`;
    
    if (level === 1) return gridCode;
    
    // 第二级极地网格：将2°×2°按经度划分为16个30′×30′网格
    // 标准化经度到0-360范围
    const normLon = ((longitude % 360) + 360) % 360;
    
    // 将360°划分为16等份，每份22.5°
    const sector = Math.floor(normLon / 22.5); // 0-15范围
    
    // 计算纬度所在行（0-3表示从极点向外的4个30′带）
    const baseLat = isPolarNorth ? 88 : -88;
    const distFromBase = Math.abs(latitude - baseLat);
    const row = Math.min(Math.floor(distFromBase / 0.5), 3); // 0-3范围
    
    // 计算二级网格码（16个网格编号为00-33）
    const level2Index = row * 4 + (sector % 4);
    const level2Code = level2Index.toString().padStart(2, '0');
    
    gridCode += level2Code;
    
    return gridCode;
  };
  
  // 计算指定位置的所有级别编码
  const calculateAllLevelCodes = (longitude: number, latitude: number) => {
    // 获取完整的各级网格码
    const level1 = calculateBeidouGridCode(longitude, latitude, 1);
    const level2 = calculateBeidouGridCode(longitude, latitude, 2);
    const level3 = calculateBeidouGridCode(longitude, latitude, 3);
    const level4 = calculateBeidouGridCode(longitude, latitude, 4);
    const level5 = calculateBeidouGridCode(longitude, latitude, 5);
    
    // 更新状态
    setGridCodes({
      level1,
      level2,
      level3,
      level4,
      level5
    });
  };
  
  // 添加鼠标点击事件监听
  useEffect(() => {
    if (!viewer || !isVisible) return;
    
    // 鼠标点击事件处理函数
    const clickHandler = (event: PointerEvent) => {
      // 获取点击位置的笛卡尔坐标
      const position = viewer.scene.pickPosition(new Cesium.Cartesian2(event.clientX, event.clientY));
      
      if (position) {
        // 转换为地理坐标
        const cartographic = Cesium.Cartographic.fromCartesian(position);
        const longitude = Cesium.Math.toDegrees(cartographic.longitude);
        const latitude = Cesium.Math.toDegrees(cartographic.latitude);
        const height = cartographic.height;
        
        // 更新选中位置
        setSelectedPosition({ longitude, latitude, height });
        
        // 计算编码
        calculateAllLevelCodes(longitude, latitude);
      }
    };
    
    // 添加点击事件监听
    const canvas = viewer.scene.canvas;
    canvas.addEventListener('click', clickHandler as EventListener);
    
    // 清理函数
    return () => {
      if (canvas) {
        canvas.removeEventListener('click', clickHandler as EventListener);
      }
    };
  }, [viewer, isVisible]);
  
  // 如果不可见则不渲染
  if (!isVisible || !selectedPosition) {
    return null;
  }
  
  return (
    <GridInfoPanel>
      <Title>北斗网格位置码信息</Title>
      
      <InfoGroup>
        <InfoLabel>点击位置坐标</InfoLabel>
        <CoordinateRow>
          <CoordinateLabel>经度:</CoordinateLabel>
          <CoordinateValue>{selectedPosition.longitude.toFixed(6)}°</CoordinateValue>
        </CoordinateRow>
        <CoordinateRow>
          <CoordinateLabel>纬度:</CoordinateLabel>
          <CoordinateValue>{selectedPosition.latitude.toFixed(6)}°</CoordinateValue>
        </CoordinateRow>
        <CoordinateRow>
          <CoordinateLabel>高度:</CoordinateLabel>
          <CoordinateValue>{Math.round(selectedPosition.height)} 米</CoordinateValue>
        </CoordinateRow>
      </InfoGroup>
      
      <InfoGroup>
        <InfoLabel>一级网格码 (6°×4°)</InfoLabel>
        <InfoValue>{gridCodes.level1}</InfoValue>
      </InfoGroup>
      
      <InfoGroup>
        <InfoLabel>二级网格码 (30′×30′)</InfoLabel>
        <InfoValue>
          <span style={{ color: '#a0cfff' }}>{gridCodes.level1}</span>
          <span style={{ color: '#ffffff' }}>{gridCodes.level2.slice(gridCodes.level1.length)}</span>
        </InfoValue>
      </InfoGroup>
      
      <InfoGroup>
        <InfoLabel>三级网格码 (15′×10′)</InfoLabel>
        <InfoValue>
          <span style={{ color: '#a0cfff' }}>{gridCodes.level2}</span>
          <span style={{ color: '#ffffff' }}>{gridCodes.level3.slice(gridCodes.level2.length)}</span>
        </InfoValue>
      </InfoGroup>
      
      <InfoGroup>
        <InfoLabel>四级网格码 (1′×1′)</InfoLabel>
        <InfoValue>
          <span style={{ color: '#a0cfff' }}>{gridCodes.level3}</span>
          <span style={{ color: '#ffffff' }}>{gridCodes.level4.slice(gridCodes.level3.length)}</span>
        </InfoValue>
      </InfoGroup>
      
      <InfoGroup>
        <InfoLabel>五级网格码 (4″×4″)</InfoLabel>
        <InfoValue>
          <span style={{ color: '#a0cfff' }}>{gridCodes.level4}</span>
          <span style={{ color: '#ffffff' }}>{gridCodes.level5.slice(gridCodes.level4.length)}</span>
        </InfoValue>
      </InfoGroup>
    </GridInfoPanel>
  );
};

export default BeidouGridTool; 